﻿using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;

public class TriangulationTool : MonoBehaviour
{
    /// <summary>用物体的坐标来代替点</summary>
    //public List<Transform> tList;
    public Transform itemList;

    public Material floorMaterial;
    public Material wallMaterial;

    private void Start()
    {
        itemList.gameObject.SetActive(true);
        #region 转坐标
        List<Vector3> posList = new List<Vector3>();

        for (int i = 0; i < itemList.childCount; i++)
        {
            Transform trans = itemList.GetChild(i);
            posList.Add(trans.position);
            trans.GetComponent<MeshRenderer>().enabled = false;
            //trans.GetComponent<MeshFilter>().
            trans.name = "Point : " + i;/*+ "P:" + trans.position.x + "," + trans.position.z;*/
        }
        #endregion

        CreatePolygon(posList, floorMaterial);
        CreatePanelMesh(posList, wallMaterial, 2);
    }
    private int[] triangles;
    private int[] arrayTriangle;
    private int[] doubleTriangle;
    private Vector2[] uvs;

    public float width;
    public float hight;

    #region 多边形mesh
    /// <summary>创建多边形</summary>
    /// <param name="posList"></param>
    /// <param name="mat"></param>
    /// <returns></returns>
    public GameObject CreatePolygon(List<Vector3> posList, Material mat)
    {
        PolygonTool.Triangulation triangulation = new PolygonTool.Triangulation(posList);
        //获取三角形顶点序列
        arrayTriangle = triangulation.GetTriangles();

        #region 如果点时顺时针的话,需要反向排序修改为逆时针的
        if (arrayTriangle == null)
        {
            Debug.Log("反向排序节点");
            posList = ReverseSort(posList);
            return CreatePolygon(posList, mat);

        }
        #endregion

        int _length = arrayTriangle.Length;

        //计算双面所以需要多一个三角形
        doubleTriangle = new int[_length * 2];

        for (int i = 0; i < _length; i++)
        {
            doubleTriangle[i] = arrayTriangle[i];
        }
        for (int i = 0; i < _length; i += 3)
        {
            doubleTriangle[i + _length] = arrayTriangle[_length - i - 3];
            doubleTriangle[i + _length + 1] = arrayTriangle[_length - i - 3 + 2];
            doubleTriangle[i + _length + 2] = arrayTriangle[_length - i - 3 + 1];
        }

        #region vertexs
        //搞定顶点
        //顶点位置
        Vector3[] vertexs = new Vector3[_length * 2];

        for (int i = 0; i < vertexs.Length; i++)
        {
            vertexs[i] = posList[doubleTriangle[i]];
        }
        #endregion

        #region triangles
        //三角形数组
        triangles = new int[_length * 2];
        //搞定序列
        for (int i = 0; i < triangles.Length; i += 3)
        {
            triangles[i] = i;
            triangles[i + 1] = i + 2;
            triangles[i + 2] = i + 1;
        }
        #endregion

        #region uv

        //找到mesh的最极端
        float l = vertexs[0].x;
        float r = vertexs[0].x;
        float u = vertexs[0].z;
        float d = vertexs[0].z;
        for (int i = 1; i < vertexs.Length; i++)
        {
            if (l > vertexs[i].x) l = vertexs[i].x;
            if (r < vertexs[i].x) r = vertexs[i].x;
            if (u < vertexs[i].z) u = vertexs[i].z;
            if (d > vertexs[i].z) d = vertexs[i].z;
        }

        float _x = r - l;
        float xb = _x / width;
        float _z = u - d;
        float zb = _z / hight;

        //计算uv和设置发现
        uvs = new Vector2[_length * 2];
        //triangles是从_length中继承,长度本身就是3的倍数
        for (int i = 0; i < triangles.Length; i += 3)
        {
            uvs[i] = new Vector2((1 - (vertexs[triangles[i]].x - l) / _x) * xb, (1 - (vertexs[triangles[i]].z - d) / _z) * zb);
            uvs[i + 2] = new Vector2((1 - (vertexs[triangles[i + 1]].x - l) / _x) * xb, (1 - (vertexs[triangles[i + 1]].z - d) / _z) * zb);
            uvs[i + 1] = new Vector2((1 - (vertexs[triangles[i + 2]].x - l) / _x) * xb, (1 - (vertexs[triangles[i + 2]].z - d) / _z) * zb);
        }
        #endregion

        #region Normals
        Vector3[] normals = new Vector3[vertexs.Length];
        for (int i = 0; i < normals.Length; i++)
        {
            normals[i] = Vector3.up;
        }
        #endregion


        GameObject tempGame = new GameObject("多边形");
        MeshFilter mf = tempGame.AddComponent<MeshFilter>();
        MeshRenderer mr = tempGame.AddComponent<MeshRenderer>();
        Mesh m = new Mesh();
        m.vertices = vertexs;
        m.triangles = triangles;
        m.uv = uvs;
        m.normals = normals;


        mf.mesh = m;
        mr.material = mat;
        return tempGame;
    }

    /// <summary>逆向排序</summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="list"></param>
    /// <returns></returns>
    public static List<T> ReverseSort<T>(List<T> list)
    {
        for (int i = 0; i < list.Count / 2; i++)
        {
            T v = list[i];
            list[i] = list[list.Count - 1 - i];
            list[list.Count - 1 - i] = v;
        }

        return list;
    }
    #endregion

    public float p_Hight;
    public float p_Width;

    //public GameObject cube;
    /// <summary>创建面</summary>
    public void CreatePanelMesh(List<Vector3> _pos1, Material mat, float height)
    {
        List<Vector3> _pos = new List<Vector3>();
        int _length = 0;
        foreach (var item in _pos1)
        {
            _pos.Add(item);
        }
        _pos.Add(_pos1[0]);
        _length = _pos.Count;
        #region vertexs
        //顶点位置
        Vector3[] vertexs = new Vector3[_length * 2];
        for (int i = 0; i < _length; i++)
        {

            vertexs[i * 2] = _pos[i];
            vertexs[i * 2 + 1] = _pos[i] + Vector3.up * height;
        }
        #endregion

        #region triangles
        //三角形数组= 点数_sildes*方块的三角形个数2*三角形的角的个数*3*面数*2
        int[] triangles = new int[_length * 12];
        for (int i = 0; i < _length - 1; i++)
        {
            //外立面两个三角形
            triangles[(i * 6 * 2) + 0] = i * 2;
            triangles[(i * 6 * 2) + 1] = i * 2 + 1;
            triangles[(i * 6 * 2) + 2] = i * 2 + 3;
            triangles[(i * 6 * 2) + 3] = i * 2;
            triangles[(i * 6 * 2) + 4] = i * 2 + 3;
            triangles[(i * 6 * 2) + 5] = i * 2 + 2;

            //内立面两个三角形
            triangles[(i * 6 * 2) + 6] = i * 2;
            triangles[(i * 6 * 2) + 7] = i * 2 + 3;
            triangles[(i * 6 * 2) + 8] = i * 2 + 1;
            triangles[(i * 6 * 2) + 9] = i * 2;
            triangles[(i * 6 * 2) + 10] = i * 2 + 2;
            triangles[(i * 6 * 2) + 11] = i * 2 + 3;

        }
        //尾部连接0点的外立面两个三角形
        triangles[((_pos.Count - 1) * 6 * 2) + 0] = (_pos.Count - 1) * 2;
        triangles[((_pos.Count - 1) * 6 * 2) + 1] = (_pos.Count - 1) * 2 + 1;
        triangles[((_pos.Count - 1) * 6 * 2) + 2] = 1;
        triangles[((_pos.Count - 1) * 6 * 2) + 3] = (_pos.Count - 1) * 2;
        triangles[((_pos.Count - 1) * 6 * 2) + 4] = 0;
        triangles[((_pos.Count - 1) * 6 * 2) + 5] = 1;
        //尾部连接0点的内立面两个三角形
        triangles[((_pos.Count - 1) * 6 * 2) + 6] = (_pos.Count - 1) * 2;
        triangles[((_pos.Count - 1) * 6 * 2) + 7] = 1;
        triangles[((_pos.Count - 1) * 6 * 2) + 8] = (_pos.Count - 1) * 2 + 1;
        triangles[((_pos.Count - 1) * 6 * 2) + 9] = (_pos.Count - 1) * 2;
        triangles[((_pos.Count - 1) * 6 * 2) + 10] = 1;
        triangles[((_pos.Count - 1) * 6 * 2) + 11] = 0;

        #endregion

        #region UV
        //最后的N点和0点重合, 所以看不到重合点
        Vector2[] uvs = new Vector2[vertexs.Length];
        float uh = height / p_Hight;
        float uw = 0;

        for (int i = 0; i < _length; i++)
        {
            float distance = 0;
            if (i != 0)
            {
                distance = Vector3.Distance(_pos[i - 1], _pos[i]);
            }
            uw = uw + distance / p_Width;
            uvs[(i * 2) + 0] = new Vector2(uw, 0);
            uvs[(i * 2) + 1] = new Vector2(uw, uh);
        }

        #endregion

        #region Normals

        Vector3[] normals = new Vector3[_length * 2];
        for (int i = 0; i < normals.Length; i++)
        {
            normals[i] = Vector3.up;
        }

        #endregion

        GameObject tempGame = new GameObject("多边形");
        MeshFilter mf = tempGame.AddComponent<MeshFilter>();
        MeshRenderer mr = tempGame.AddComponent<MeshRenderer>();
        mr.shadowCastingMode = ShadowCastingMode.Off;
        Mesh m = new Mesh();
        m.vertices = vertexs;
        m.triangles = triangles;
        m.uv = uvs;
        m.normals = normals;

        mf.mesh = m;
        mr.material = mat;
    }

    float m = 0;
    private void Update()
    {
        wallMaterial.SetTextureOffset("_MainTex", new Vector2( m += Time.deltaTime*0.1f,1));
    }
}
